Train your first neural network: basic classification

  • Ziel: Training eines neuronales Netzwerk, um Bilder von Kleidung, wie Turnschuhe und Hemden, zu klassifizieren.
  • Verwendung von tf.keras, eine highlevel API, basierend auf Tensorflow zum Erstellen und Trainieren von Modellen in TensorFlow.
In [1]:
from __future__ import absolute_import, division, print_function, unicode_literals
In [2]:
# TensorFlow and tf.keras
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
from tensorflow import keras
# Helper libraries
import numpy as np
import matplotlib.pyplot as plt
WARNING: Logging before flag parsing goes to stderr.
W0726 08:12:35.568381 19140 deprecation.py:323] From C:\Users\gp4211\AppData\Local\Continuum\anaconda3\envs\tf2\lib\site-packages\tensorflow\python\compat\v2_compat.py:65: disable_resource_variables (from tensorflow.python.ops.variable_scope) is deprecated and will be removed in a future version.
Instructions for updating:
non-resource variables are not supported in the long term

Import the Fashion MNIST dataset

  • Trainingsdaten: Fashion MNIST-Datensatz
  • 70.000 Bilder in 10 Kategorien
  • ein Bild zeigt ein Kleidungsstücke in niedriger Auflösung (28 x 28 Pixel),
Fashion MNIST sprite
Figure 1. Fashion-MNIST samples (by Zalando, MIT License).
 

Fashion MNIST ist als Ersatz für den klassischen Datensatz MNIST gedacht - oft als "Hello, World" von maschinellen Lernprogrammen für die Computer-Vision. Der MNIST-Datensatz enthält Bilder von handschriftlichen Ziffern (0, 1, 2, etc.) in einem identischen Format zu den Kleidungsstücken, die wir hier verwenden werden.

Dieser Leitfaden verwendet Fashion MNIST für Abwechslung und weil es ein etwas anspruchsvolleres Problem ist als normales MNIST. Beide Datensätze sind relativ klein und werden verwendet, um zu überprüfen, ob ein Algorithmus wie erwartet funktioniert. Sie sind gute Ausgangspunkte, um Code zu testen und zu debuggen.

Wir werden 60.000 Bilder verwenden, um das Netzwerk zu trainieren, und 10.000 Bilder, um zu bewerten, wie genau das Netzwerk gelernt hat, Bilder zu klassifizieren.

In [3]:
#Download Dataset and split in train images, train labels, test images, test labels
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
  • Bilder sind 28x28 NumPy-Arrays,
  • Pixelwerten zwischen 0 und 255.
  • Die labels sind eine Reihe von ganzen Zahlen, die von 0 bis 9 reichen. Diese entsprechen der Klasse der Kleidung, die das Bild repräsentiert:
Label Class
0 T-shirt/top
1 Trouser
2 Pullover
3 Dress
4 Coat
5 Sandal
6 Shirt
7 Sneaker
8 Bag
9 Ankle boot
In [4]:
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

Explore the data

In [5]:
train_images.shape
Out[5]:
(60000, 28, 28)
  • 60.000 Bilder im Trainingsset
  • jedes Bild 28 x 28 Pixel
In [6]:
len(train_labels)
Out[6]:
60000
  • Dementsprechend 60.000 Labels im Trainingsset
In [7]:
train_labels
Out[7]:
array([9, 0, 0, ..., 3, 0, 5], dtype=uint8)
  • Jedes Label ist eine ganze Zahl zwischen 0 und 9

Es befinden sich 10.000 Bilder im Testset. Auch hier wird jedes Bild als 28 x 28 Pixel dargestellt:

In [8]:
test_images.shape
Out[8]:
(10000, 28, 28)

Und das Testset enthält 10.000 Bild-Label:

In [9]:
len(test_labels)
Out[9]:
10000

Preprocess the data

  • Die Daten müssen vor dem Training des Netzwerks vorverarbeitet werden.
  • Wenn Sie das erste Bild im Trainingsset betrachten, werden Sie feststellen, dass die Pixelwerte im Bereich von 0 bis 255 liegen:
In [10]:
plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()
  • skalieren der Pixelwerte auf einen Bereich von 0 bis 1
  • teilen der Werte durch 255.
  • Wichtig: Anwenden auf sowohl Trainingsset als auch das Testset
In [11]:
train_images = train_images / 255.0
test_images = test_images / 255.0

Zeigen Sie die ersten 25 Bilder aus dem Trainingssatz an und zeigen Sie den Klassennamen unter jedem Bild an. Stellen Sie sicher, dass die Daten im richtigen Format vorliegen und wir sind bereit, das Netzwerk aufzubauen und zu trainieren.

In [12]:
plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5,5,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.binary)
    plt.xlabel(class_names[train_labels[i]])
plt.show()

Build the model

  • Neuronale Netze bestehen aus Schichten
  • Die meisten Schichten besitzen Gewichte
  • Während des Training werden diese Gewichte gelernt

Setup the layers

Der Grundbaustein eines neuronalen Netzwerks ist die Schicht. Schichten extrahieren Darstellungen aus den in sie eingegebenen Daten. Und hoffentlich sind diese Darstellungen für das jeweilige Problem sinnvoller.

Der größte Teil des tiefen Lernens besteht darin, einfache Schichten miteinander zu verbinden. Die meisten Layer, wie z.B. tf.keras.layers.Dense, haben Parameter, die während des Trainings gelernt werden.

In [13]:
model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation=tf.nn.relu),
    keras.layers.Dense(10, activation=tf.nn.softmax)
])
In [14]:
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
flatten (Flatten)            (None, 784)               0         
_________________________________________________________________
dense (Dense)                (None, 128)               100480    
_________________________________________________________________
dense_1 (Dense)              (None, 10)                1290      
=================================================================
Total params: 101,770
Trainable params: 101,770
Non-trainable params: 0
_________________________________________________________________
In [15]:
784*128 + 128 * 10 + 128 + 10
Out[15]:
101770

Compile the model

  • Optimizer - Methode wie Gewichte angepasst werden -> stochastic gradient descent
  • Verlustfunktion - misst wie groß der Fehler während des Trainings ist
  • Metrics - Trainings- und Testschritte werden anhand der Accuracy überwachtzu überwachen.
In [16]:
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

Train the model

Um mit dem Training zu beginnen, rufen Sie die Methode "model.fit" auf - das Modell ist "fit" zu den Trainingsdaten:

In [45]:
model.fit(train_images, train_labels, epochs=5)
Train on 60000 samples
Epoch 1/5
60000/60000 [==============================] - 3s 47us/sample - loss: 0.1740 - acc: 0.9349
Epoch 2/5
60000/60000 [==============================] - 3s 48us/sample - loss: 0.1698 - acc: 0.9358
Epoch 3/5
60000/60000 [==============================] - 3s 47us/sample - loss: 0.1660 - acc: 0.9370
Epoch 4/5
60000/60000 [==============================] - 3s 49us/sample - loss: 0.1607 - acc: 0.9402
Epoch 5/5
60000/60000 [==============================] - 3s 48us/sample - loss: 0.1594 - acc: 0.9392
Out[45]:
<tensorflow.python.keras.callbacks.History at 0x242831744a8>

Während das Modell trainiert, werden die Verlust- und Genauigkeitsmetriken angezeigt. Dieses Modell erreicht eine Genauigkeit von etwa 93% auf die Trainingsdaten.

Evaluate accuracy

  • Das Model wird danach anhand des Testdatensatzes evaluiert:
In [46]:
test_loss, test_acc = model.evaluate(test_images, test_labels)

print('Test accuracy:', test_acc)
10000/10000 [==============================] - 0s 29us/sample - loss: 0.3895 - acc: 0.8869
Test accuracy: 0.8869
  • Genauigkeit des Testdatensatzes etwas geringer
  • Dieser Unterschied zwischen Trainingsgenauigkeit und Testgenauigkeit ist ein Beispiel für eine overfitting
  • Overfitting ist, wenn ein Modell des maschinellen Lernens bei neuen Daten schlechter abschneidet als bei Trainingsdaten

Make predictions

Mit dem trainierten Modell können wir damit Vorhersagen über einige Bilder treffen.

In [47]:
predictions = model.predict(test_images)
  • das Modell hat das Label für jedes Bild im Testset vorhergesagt
  • Werfen wir einen Blick auf die erste Vorhersage:
In [48]:
predictions[0]
Out[48]:
array([3.2200684e-10, 1.1447482e-14, 1.0274544e-13, 2.1138345e-15,
       6.1082553e-16, 1.2213195e-06, 4.3457222e-14, 4.9445494e-05,
       8.3547904e-13, 9.9994934e-01], dtype=float32)
  • Vorhersage ist ein Array von 10 Zahlen
  • Diese beschreiben das "Vertrauen" des Modells, dass das Bild jedem der 10 verschiedenen Kleidungsstücke entspricht.
  • Wir können sehen, welches Label den höchsten Vertrauenswert hat:
In [49]:
np.argmax(predictions[0])
Out[49]:
9
Label Class
0 T-shirt/top
1 Trouser
2 Pullover
3 Dress
4 Coat
5 Sandal
6 Shirt
7 Sneaker
8 Bag
9 Ankle boot
In [50]:
plt.figure()
plt.imshow(test_images[0])
Out[50]:
<matplotlib.image.AxesImage at 0x24284956390>
  • Wir können dies grafisch darstellen, um den vollen Satz der 10 Klassenvorhersagen zu betrachten.
In [23]:
def plot_image(i, predictions_array, true_label, img):
  predictions_array, true_label, img = predictions_array[i], true_label[i], img[i]
  plt.grid(False)
  plt.xticks([])
  plt.yticks([])
  
  plt.imshow(img, cmap=plt.cm.binary)
  
  predicted_label = np.argmax(predictions_array)
  if predicted_label == true_label:
    color = 'blue'
  else:
    color = 'red'
  
  plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
                                100*np.max(predictions_array),
                                class_names[true_label]),
                                color=color)

def plot_value_array(i, predictions_array, true_label):
  predictions_array, true_label = predictions_array[i], true_label[i]
  plt.grid(False)
  plt.xticks([])
  plt.yticks([])
  thisplot = plt.bar(range(10), predictions_array, color="#777777")
  plt.ylim([0, 1])
  predicted_label = np.argmax(predictions_array)
  
  thisplot[predicted_label].set_color('red')
  thisplot[true_label].set_color('blue')
In [54]:
#Note to myself: try image Nr.12
i = 12
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i, predictions, test_labels, test_images)
plt.subplot(1,2,2)
plot_value_array(i, predictions,  test_labels)
plt.show() 

Lassen Sie uns mehrere Bilder mit ihren Vorhersagen plotten. Korrekte Vorhersagekennzeichen sind blau und falsche Vorhersagekennzeichen rot. Die Zahl gibt den Prozentsatz (von 100) für das vorhergesagte Etikett an. Beachten Sie, dass es auch bei großer Zuversicht falsch sein kann.

In [55]:
num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
  plt.subplot(num_rows, 2*num_cols, 2*i+1)
  plot_image(i, predictions, test_labels, test_images)
  plt.subplot(num_rows, 2*num_cols, 2*i+2)
  plot_value_array(i, predictions, test_labels)
plt.show()

Verwenden Sie schließlich das trainierte Modell, um eine Vorhersage über ein einzelnes Bild zu machen.

In [26]:
# Grab an image from the test dataset
img = test_images[0]

print(img.shape)
(28, 28)

tf.keras Modelle sind optimiert, um Vorhersagen über eine Batch oder Sammlung von Beispielen auf einmal zu machen. Obwohl wir also ein einzelnes Bild verwenden, müssen wir es zu einer Liste hinzufügen:

In [27]:
# Add the image to a batch where it's the only member.
img = (np.expand_dims(img,0))

print(img.shape)
(1, 28, 28)

Prognostiziere nun das Bild:

In [28]:
predictions_single = model.predict(img)

print(predictions_single)
[[2.7304031e-06 1.5697024e-08 5.4862483e-07 5.9942025e-08 5.7119377e-07
  1.9029843e-02 2.6997100e-06 2.3414434e-03 2.9866385e-05 9.7859222e-01]]
In [29]:
plot_value_array(0, predictions_single, test_labels)
plt.xticks(range(10), class_names, rotation=45)
plt.show()

model.predict gibt eine Liste von Listen zurück, eine für jedes Bild im Datenstapel. Hol dir die Vorhersagen für unser (einziges) Bild im Stapel:

In [30]:
prediction_result = np.argmax(predictions_single[0])
print(prediction_result)
9

Und wie bisher prognostiziert das Modell ein Label von 9.

In [ ]: